<script setup lang="ts" name="GoodsSku">
import { GoodsInfo ,Spec,SpecValue} from '@/types/goods';
import bwPowerSet from '@/utils/bwPowerSet'
const emit =defineEmits<{
  ( e:'changeSku' , skuId:string):void
}>()
//sku组件使用：
//1.必须项：传入商品信息对象=》拥有了启用禁用等功能
//2.可选项：传入skuId     =》默认回显，默认让一下规格选择
//3 子传父：当全部规格选完，就确定了一个sku，需要子传父，将skuId传给父即可
const props=defineProps<{
    goods:GoodsInfo
    skuId?: string
}>()
const SPLIT_STR = '+'
// 一进入页面，控制启用禁用状态=>需要路径字典,根据sku数据获得路径字典
const getPathMap=()=>{
  const pathMap:{
    [key : string] :string[]
  } = {}
  // 1.得到有库存的skus
  const skus = props.goods.skus.filter(item=>item.inventory!==0)
  // 2. 遍历有效的skus, 获取单独的sku, 进行处理
  skus.forEach((sku)=>{
    // 3. 整理数据， 整理得到 [属性1, 属性2, 属性3]
    const arr = sku.specs.map(item=>item.valueName)
    // 4. 基于整理的属性列表， 求子集
    const powerSet = bwPowerSet(arr)
    // console.log(powerSet)
    powerSet.forEach(sub=>{
      const key = sub.join(SPLIT_STR)

      if(key in pathMap){
        pathMap[key].push(sku.id)
      }else{
        pathMap[key]=[sku.id]
      }
    })
  })
  // console.log(pathMap);
  return  pathMap
}
//点击事件函数
const changeSelected = (spec:Spec , specValue:SpecValue) => {
  //如果是禁用的状态，就不添加selected类
  if(specValue.disabled) return
  //如果是选中状态，再次点击就取消
  if(specValue.selected){
    specValue.selected=false
  }else{
    //排他，把所有的都取消，在把当前选中
    spec.values.forEach(v=>v.selected=false)
    specValue.selected=true
  }
  //按钮重新选择，状态也要需要更新
  updateDisabledStatus()
//   // 购物车，当全选了就传递对应的skuId----------------------------
//   //selectedArr是单个sku
//   const selectedArr = getSelectedSpec().filter((item) => item)

//   if (selectedArr.length === props.goods.specs.length) {
//   // 2. 去pathMap找到对应的skuid
//   const key = selectedArr.join('★')
//   const [skuId] = pathMap[key]
//   // 3. 子传父，给父组件
//   emit('changeSku', skuId)
// } else {
//   emit('changeSku', '')
// }
 // --------------------------------------------------------
  //1.判断是否选中所有的规格，都选中就确定了一个sku
 const selectArr = getSelectedSpec().filter(item=>item)
 if(selectArr.length === props.goods.specs.length){
   //2.选中之后，子传父需要传的是skuId，所以把数组转字符串，去字典里找id
  const result = pathMap[selectArr.join(SPLIT_STR)]
  const skuId = result[0] //规格全部选中，只会有一个唯一值
  emit('changeSku',skuId)
 }else{
  emit('changeSku','')

 }
}
//更新默认的启用禁用状态
const updateDisabledStatus=()=>{
  const selectArr = getSelectedSpec() //['','','']

  props.goods.specs.forEach((spec,index)=>{
    // props.goods.specs 是spu的所有规格
    // spec.values 是spu的每个单独规格
    // specValue 是当前单独规格的每一项
    // console.log(spec);
    
    
    spec.values.forEach((specValue)=>{
      //不能修改原数组
      const tempArr=[...selectArr]  //['黑色', '', '']
      tempArr[index] = specValue.name //使用外层的index，才能一一对应

      const key =tempArr.filter(item => item).join(SPLIT_STR)  //'黑色'
      //tempArr是一个数组，但是字典里是字符串，所以使用key判断
      if(key in pathMap){ //判断组合状态在不在路径字典里
        //存在，说明有库存，不需要禁用
        specValue.disabled=false
      }else{
        //不存在，说明没有库存，禁用
        specValue.disabled=true
      }
    })
  })
}
//获取当前选中状态
const getSelectedSpec=()=>{
  const arr = ['','','']
  props.goods.specs.forEach((spec,index)=>{
    //当前选中的对象的name，放到arr数组中
   const tempObj= spec.values.find(specValue=>specValue.selected)
   //  console.log(tempObj);
    arr[index] = tempObj ? tempObj.name : ''
  })
  return arr
}
//根据父传子传递的skuId，回显
const initSelectedSpec=()=>{
  //没传不执行
  if(!props.skuId) return  
  //找到skuId对应的sku
  const sku = props.goods.skus.find(item=>item.id===props.skuId)
  if(!sku) return //没找到也不执行
  props.goods.specs.forEach((spec,index)=>{
   // console.log(sku.specs[index].valueName);
   //find 找到每个规格中只有一个符合
   const text = sku.specs[index].valueName
   const specValue= spec.values.find(item=>item.name === text)
   specValue!.selected = true
  })
}
//1.获取路径字典
const pathMap = getPathMap()
// console.log('字典',pathMap);
//2.按照skuId，初始化选中状态
initSelectedSpec()
//3.更新禁用状态
updateDisabledStatus()
</script>



<template>
  <div class="goods-sku">
    <dl v-for="item in goods.specs" :key="item.name">
      <dt>{{item.name}}</dt>
      <dd>

        <template v-for="sub in item.values" :key="sub.name">
         <img
         v-if="sub.picture"
          @click="changeSelected(item,sub)"
          :class="{ selected : sub.selected , disabled:sub.disabled }"
          :src="sub.picture"
          alt=""
        />
          <span v-else
          :class="{ selected : sub.selected , disabled:sub.disabled }"
          @click="changeSelected(item,sub)"
          >{{ sub.name }}</span>
        </template>

      </dd>
    </dl>
    <!-- <dl>
      <dt>尺寸</dt>
      <dd>
        <span class="disabled">10英寸</span>
        <span class="selected">20英寸</span>
        <span>30英寸</span>
      </dd>
    </dl>
    <dl>
      <dt>版本</dt>
      <dd>
        <span>美版</span>
        <span>港版</span>
      </dd>
    </dl> -->
  </div>
</template>

<style scoped lang="less">
.sku-state-mixin () {
  border: 1px solid #e4e4e4;
  margin-right: 10px;
  cursor: pointer;
  &.selected {
    border-color: @xtxColor;
  }
  &.disabled {
    opacity: 0.6;
    border-style: dashed;
    cursor: not-allowed;
  }
}
.goods-sku {
  padding-left: 10px;
  padding-top: 20px;
  dl {
    display: flex;
    padding-bottom: 20px;
    align-items: center;
    dt {
      width: 50px;
      color: #999;
    }
    dd {
      flex: 1;
      color: #666;
      > img {
        width: 50px;
        height: 50px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
      > span {
        display: inline-block;
        height: 30px;
        line-height: 30px;
        padding: 0 20px;
        margin-top: 5px;
        .sku-state-mixin ();
      }
    }
  }
}
</style>


